﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;


namespace searchString
{
    public partial class searchStrFrom : Form
    {
        public searchStrFrom()
        {
            InitializeComponent();
        }

        string targetStr = "";
        string rootDir = "";

        private void btnOpenDir_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog folderDialog = new FolderBrowserDialog();
            folderDialog.Description = "set the path to search";
            folderDialog.ShowNewFolderButton = false;
            if(rootDir !="")
                folderDialog.SelectedPath = rootDir;

            if(folderDialog.ShowDialog() == DialogResult.OK)
            {
                rootDir = folderDialog.SelectedPath;
                richText.AppendText(rootDir + "\n\n");

                this.Text = "searchString------" + rootDir;
            }

        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            targetStr = textBox1.Text.ToString();
        }

        

        private void btnSearch_Click(object sender, EventArgs e)
        {
            richText.Clear();
            richText.AppendText(rootDir + "\n\n");
            listView1.View = View.List;
            listView1.Items.Clear();
            scanFolder sf = new scanFolder();
            sf.getAllFiles(rootDir, listView1);

            if (targetStr == "") return;
            for (int i = 0; i < listView1.Items.Count; i++)
            {
                try
                {
                    //richText.AppendText(listView1.Items[i].Name.ToString() + "\n");
                    StreamReader rd = new StreamReader(listView1.Items[i].Name.ToString(), Encoding.Default);
                    List<string> targetLines = sf.searchString(rd, targetStr);
                    if (targetLines.Count > 0)
                    {
                        listView1.Items[i].BackColor = Color.Red;
                        
                        richText.AppendText(listView1.Items[i].Name.ToString() + "\n");
                        for (int j = 0; j < targetLines.Count; j++)
                        {
                            richText.AppendText(targetLines[j]  + "\n");
                        }
                    }
                    rd.Close();
                }
                catch
                {
                    continue;
                }
            }
            coloredTargetStr(richText, targetStr);
        }

        private void coloredTargetStr(RichTextBox richTB, string str)
        {
            //char[] targetStr = str.ToCharArray();
            var index = richTB.Find(str,RichTextBoxFinds.WholeWord);
            int startPos = index;
            int nextIndex = -1;
            while(nextIndex != startPos)  //search the target string by the find function and set the color 
            {
                richTB.SelectionStart = index;
                richTB.SelectionLength = str.Length;
                richTB.SelectionBackColor = Color.Red;
                richTB.Focus();
                nextIndex = richTB.Find(str, index + str.Length,RichTextBoxFinds.WholeWord);
                if(nextIndex == -1)
                    nextIndex = startPos;
                index = nextIndex;
            }
        }

        private void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            var items = this.listView1.SelectedItems;
            foreach(ListViewItem item in items)
            {
                try
                {
                    Process.Start(item.Name);
                }
                catch
                {
                    Process.Start("notepad.exe", item.Name);
                }
            }
        }

        private void listView1_SelectedIndexChanged(object sender, EventArgs e)
        {
            var items = this.listView1.SelectedItems;
            foreach (ListViewItem item in items)
            {
                //item.BackColor = Color.Yellow;
                listView1.Focus();
                var index = richText.Find(item.Name, RichTextBoxFinds.WholeWord);
                int startPos = index;
                int nextIndex = -1;
                while (nextIndex != startPos)  //search the target string by the find function and set the color 
                {
                    richText.SelectionStart = index;
                    richText.SelectionLength = item.Name.Length;
                    //richText.SelectionBackColor = Color.Yellow;
                    richText.Focus();
                    nextIndex = richText.Find(item.Name, index + item.Name.Length, RichTextBoxFinds.WholeWord);
                    if (nextIndex == -1)
                        nextIndex = startPos;
                    index = nextIndex;
                }    

            }
        }

        private void copy_Click(object sender, EventArgs e)
        {
            this.richText.Copy();
        }

        private void font_Click(object sender, EventArgs e)
        {
            try
            {
                double size = Convert.ToDouble(Microsoft.VisualBasic.Interaction.InputBox("Font size", "set the new font size"));
                Font font = new Font(FontFamily.GenericMonospace, (float)size, FontStyle.Regular);
                this.richText.Font = font;
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void brouse_Click(object sender, EventArgs e)
        {
            var items = this.listView1.SelectedItems;
            foreach (ListViewItem item in items)
            {

                try
                {
                    FileInfo f = new FileInfo(item.Name);
                    Process.Start(f.Directory.ToString());
                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }
        }

        private void open_Click(object sender, EventArgs e)
        {
            try
            {
                Process.Start(@richText.SelectedText.Trim());
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        
        

        
    }


    public class scanFolder
    {
        public void getAllFiles(string directory, ListView listB) //获取指定的目录中的所有文件（包括文件夹）
        {
            getFiles(directory, listB);//获取指定的目录中的所有文件（不包括文件夹）
            getDirectory(directory, listB);//获取指定的目录中的所有目录（文件夹）
        }

        public void getFiles(string directory, ListView listB) //获取指定的目录中的所有文件（不包括文件夹）
        {
            try
            {
                string[] path = System.IO.Directory.GetFiles(directory);
                for (int i = 0; i < path.Length; i++)
                {
                    listB.Items.Add(path[i]);
                    listB.Items[listB.Items.Count - 1].Name = path[i];
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        public void getDirectory(string directory, ListView listB) //获取指定的目录中的所有目录（文件夹）
        {
            string[] directorys;
            try
            {
                directorys = System.IO.Directory.GetDirectories(directory);
                
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return;
            }
            if (directorys.Length <= 0) //如果该目录总没有其他文件夹
                return;
            else
            {
                for (int i = 0; i < directorys.Length; i++)
                    getAllFiles(directorys[i], listB);
            }
            
        }

        public List<string> searchString(StreamReader sr, string targetStr)
        {
            List<string> searchResult = new List<string>();
            int lineNum = 0;
            while (!sr.EndOfStream)
            {
                lineNum++;
                string s = sr.ReadLine();
                if (s.Contains(targetStr))
                    searchResult.Add("line" + lineNum.ToString() + ": " + s);
            }
            return searchResult;
        }
    }
}
